{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "source": [
    "import numpy as np\n",
    "def selection_sort(x):\n",
    "    for i in range(len(x)):\n",
    "        swap = i + np.argmin(x[i:])\n",
    "        (x[i],x[swap]) = (x[swap], x[i])\n",
    "    return x\n",
    "\n",
    "x = np.array([2,1,4,3,5])\n",
    "selection_sort(x)"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4, 5])"
      ]
     },
     "metadata": {},
     "execution_count": 2
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "source": [
    "def bogosort(x):\n",
    "    while np.any(x[:-1] > x[1:]):\n",
    "        np.random.shuffle(x)\n",
    "    return x\n",
    "\n",
    "x = np.array([2,1,4,3,5])\n",
    "bogosort(x)"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4, 5])"
      ]
     },
     "metadata": {},
     "execution_count": 3
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "尽管Python有内置的sort和sorted函数可以对列表进行排序，但是这里不会介绍这两个函数，因为NumPy的np.sort函数实际上效率更高。默认情况下，np.sort的排序算法是快速排序，其算法复杂度为[N log N  ]，另外也可以选择归并排序和堆排序。对于大多数应用场景，默认的快速排序已经足够高效了。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "source": [
    "x = np.array([2,1,4,3,5])\n",
    "np.sort(x)\n",
    "x.sort() #如果希望用排好序的数组替代原始数组，可以使用数组的sort方法"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "source": [
    "x = np.array([2,1,4,3,5])\n",
    "i = np.argsort(x)  #另外一个相关的函数是argsort，该函数返回的是原始数组排好序的索引值\n",
    "print(i)"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "[1 0 3 2 4]\n"
     ]
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "source": [
    "rand = np.random.RandomState(42)\n",
    "X = rand.randint(0,10,(4,6))\n",
    "print(X)\n",
    "np.sort(X,axis=0)  #对X的每一列排序"
   ],
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "[[6 3 7 4 6 9]\n",
      " [2 6 7 4 3 7]\n",
      " [7 2 5 4 1 7]\n",
      " [5 1 4 0 9 5]]\n"
     ]
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([[2, 1, 4, 0, 1, 5],\n",
       "       [5, 2, 5, 4, 3, 7],\n",
       "       [6, 3, 7, 4, 6, 7],\n",
       "       [7, 6, 7, 4, 9, 9]])"
      ]
     },
     "metadata": {},
     "execution_count": 6
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "部分排序 分隔\n",
    "有时候我们不希望对整个数组进行排序，仅仅希望找到数组中第K小的值，NumPy的np.partition函数提供了该功能。"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "source": [
    "x =np.array([7,2,3,1,6,5,4])\n",
    "np.partition(x,3)  #请注意，结果数组中前三个值是数组中最小的三个值，剩下的位置是原始数组剩下的值。在这两个分隔区间中，元素都是任意排列的。左侧是小于3的数字，而右侧是排好顺序的数组"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([2, 1, 3, 4, 6, 5, 7])"
      ]
     },
     "metadata": {},
     "execution_count": 9
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "source": [
    "np.partition(X, 4, axis=1)"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([[6, 6, 3, 4, 7, 9],\n",
       "       [3, 2, 6, 4, 7, 7],\n",
       "       [1, 5, 2, 4, 7, 7],\n",
       "       [0, 4, 1, 5, 5, 9]])"
      ]
     },
     "metadata": {},
     "execution_count": 12
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "最后，正如np.argsort函数计算的是排序的索引值，也有一个np.argpartition函数计算的是分隔的索引值"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "source": [
    "X = rand.rand(10,2)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn;seaborn.set()\n",
    "plt.scatter(X[:,0], X[:,1], s =100)"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x7f73d0e1d690>"
      ]
     },
     "metadata": {},
     "execution_count": 15
    },
    {
     "output_type": "display_data",
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {}
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "source": [
    "dist_sq = np.sum((X[:,np.newaxis,:] - X[np.newaxis,:,:])**2, axis=-1)\n",
    "dist_sq.diagonal()\n",
    "dist_sq.shape"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "(10, 10)"
      ]
     },
     "metadata": {},
     "execution_count": 17
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "source": [
    "nearest = np.argsort(dist_sq, axis=1)\n",
    "nearest"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([[0, 3, 9, 7, 1, 4, 2, 5, 6, 8],\n",
       "       [1, 4, 7, 9, 3, 6, 8, 5, 0, 2],\n",
       "       [2, 1, 4, 6, 3, 0, 8, 9, 7, 5],\n",
       "       [3, 9, 7, 0, 1, 4, 5, 8, 6, 2],\n",
       "       [4, 1, 8, 5, 6, 7, 9, 3, 0, 2],\n",
       "       [5, 8, 6, 4, 1, 7, 9, 3, 2, 0],\n",
       "       [6, 8, 5, 4, 1, 7, 9, 3, 2, 0],\n",
       "       [7, 9, 3, 1, 4, 0, 5, 8, 6, 2],\n",
       "       [8, 5, 6, 4, 1, 7, 9, 3, 2, 0],\n",
       "       [9, 7, 3, 0, 1, 4, 5, 8, 6, 2]])"
      ]
     },
     "metadata": {},
     "execution_count": 18
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "如果使用全排序，我们实际上可以实现的比这个例子展示的更多。如果我们仅仅关心k个最近邻，那么唯一需要做的是分隔每一行，这样最小的k + 1的平方距离将排在最前面，其他更长的距离占据矩阵该行的其他位置。可以用np.argpartition函数实现："
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "source": [
    "K = 2\n",
    "nearest_partition = np.argpartition(dist_sq, K+1, axis=1)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "source": [
    "for i in range(X.shape[0]):\n",
    "    for j in nearest_partition[i, :K+1]:\n",
    "        plt.plot(*zip(X[j], X[i]), color= \"black\")"
   ],
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {}
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [],
   "outputs": [],
   "metadata": {}
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "0bedf3452ed48e38a2b75ff9f66ce8ae9ae2e92e8665cb618ee0797d2f46b9e5"
  },
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.8.10 64-bit ('d2l-zh': conda)"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}